﻿﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.WindowsAzure.StorageClient;


namespace MyLib
{
  //[DataServiceKey("PartitionKey", "RowKey")]
  public class GenericTableEntity : TableServiceEntity
  {
    public GenericTableEntity() { }

    public GenericTableEntity(GenericTableEntity e)
    {
      this.PartitionKey = e.PartitionKey;
      this.RowKey = e.RowKey;
      this.Timestamp = e.Timestamp;
      this.properties = e.properties;
    }

    public  object this[string key]
    {
      get
      {
        return this.properties[key];
      }

      set
      {
        this.properties[key] = value;
      }
    }

    public string Key()
    {
      string key = string.Empty;
      if (RowKey != null)
      {
        key = RowKey;
      }
      if (PartitionKey != null)
      {
        key = PartitionKey + "|" + key;
      }
      return key;
    }

    private Dictionary<string, object> properties = new Dictionary<string, object>();
    public Dictionary<string, object> Properties
    {
      get
      {
        return properties;
      }
      set
      {
        properties = value;
      }
    }

    public override string ToString()
    {
      StringBuilder sb = new StringBuilder();
      string value;
      string separator=";";

      sb.Append(this.PartitionKey); sb.Append(separator);
      sb.Append(this.RowKey); sb.Append(separator);
      sb.Append(this.Timestamp); sb.Append(separator);

      if (properties != null)
      {
        foreach (KeyValuePair<string, object> kvp in properties)
        {
          if (kvp.Value == null)
            value = string.Empty;
          else
            value = kvp.Value.ToString();
          //sb.Append(kvp.Key + "=" + value);
          sb.Append(value);
          sb.Append(";");
        }
      }
      return sb.ToString();
    }

    public string ToXml()
    {
      StringBuilder sb = new StringBuilder();
      sb.AppendLine("<entity>");
      sb.AppendLine("  <PartitionKey>" + this.PartitionKey + "</PartitionKey>");
      sb.AppendLine("  <RowKey>" + this.RowKey + "</RowKey>");

      string value;
      if (properties != null)
      {
        foreach (KeyValuePair<string, object> kvp in properties)
        {
          if (kvp.Value == null)
            value = string.Empty;
          else
            value = kvp.Value.ToString();
          sb.AppendLine("  <" + kvp.Key + ">" + value + "</" + kvp.Key + ">");
        }
      }

      sb.Append("</entity>");
      return sb.ToString();
    }

    public string ToXmlBinaryValues()
    {
      StringBuilder sb = new StringBuilder();
      sb.AppendLine("<entity>");
      sb.AppendLine("  <PartitionKey>" + this.PartitionKey + "</PartitionKey>");
      sb.AppendLine("  <RowKey>" + this.RowKey + "</RowKey>");

      string value;
      if (properties != null)
      {
        foreach (KeyValuePair<string, object> kvp in properties)
        {
          if (kvp.Value == null)
            value = string.Empty;
          else
            value = kvp.Value.ToString();

          value = DisplayCharsAsBytes(value.ToCharArray());

          sb.AppendLine("  <" + kvp.Key + ">" + value + "</" + kvp.Key + ">");
        }
      }

      sb.AppendLine("</entity>");
      return sb.ToString();
    }

    /// Convert a byte sequence into a displayable multi-line string showing the values.
    /// </summary>
    /// <param name="bytes"></param>
    /// <returns></returns>
    private string DisplayBytes(byte[] bytes)
    {
      StringBuilder sb = new StringBuilder();

      for (int b = 0; b < bytes.Length; b++)
        sb.Append(String.Format("{0:X2}", bytes[b]) + " ");
      return sb.ToString();
    }

    private string DisplayCharsAsBytes(char[] chars)
    {
      StringBuilder sb = new StringBuilder();

      for (int b = 0; b < chars.Length; b++)
        sb.Append(String.Format("{0:X4}", Convert.ToInt64(char.GetNumericValue(chars[b]))) + " ");
      return sb.ToString();
    }
  }

}
